package org.dtrd.modules.achievement.service;

import com.baomidou.mybatisplus.extension.service.IService;
import org.dtrd.modules.achievement.entity.bean.PatientSigninRecord;
import org.dtrd.modules.achievement.entity.bean.PatientSigninStatusBean;
import org.dtrd.modules.achievement.entity.bean.SignInAction;
import org.dtrd.modules.achievement.entity.bean.SigninRecord;
import org.dtrd.modules.achievement.entity.po.DtrdEntRdSigninRecord;
import org.dtrd.modules.patient.entity.bean.miniprogram.PatientMiniProgramSigninStatus;
import org.dtrd.modules.patient.entity.bean.report.ReportTable;
import org.dtrd.modules.record.entity.bean.DailyRecord;
import org.dtrd.modules.record.entity.bean.CheckinRecord;
import org.dtrd.modules.record.entity.bean.CheckinRecord.RecordBuilder;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * @author 萧
 * @date 2021-09-21 22:50:23
 **/
public interface IDtrdEntRdSigninRecordService extends IService<DtrdEntRdSigninRecord> {

    /**
     * 初始化打打卡记录
     *
     * @param patientId
     */
    void initSignInRecord(Integer patientId);

    DtrdEntRdSigninRecord initSignInRecord(Integer patientId, String signinPlan, Date recordDate);

    SigninRecord getSigninRecordByPatientIdAndDate(@NotNull Integer patientId, @Nullable String date);

    List<PatientSigninRecord> getPatientSigninRecords(@NotNull Integer patientId, @Nullable String date);

    /**
     * 遍历发送提醒、变更提醒与漏打标记
     *
     * @param isFirstRemind 当天第一次遍历
     */
    void sendRemindForAll(boolean isFirstRemind);

    void sendRemind(Integer patientId, Integer recordType, Integer subType);

    /**
     * 获取指定时间范围内的打卡完成平均率
     */
    Integer getSigninFinishedAvgRate(Integer patientId, Date startDate, Date endDate);

    /**
     * 获取患者指定打卡范围内容的打卡完成率
     */
    Map<Date, Integer> getSigninFinishedRateMap(Integer patientId, Date startDate, Date endDate);

    /**
     * 获取本周一到今天的打卡完成率
     */
    Integer getSigninFinishedThisWeek(Integer patientId);

    /**
     * 发送单条提醒
     *
     * @param record
     * @param patientId
     * @param signInActionList
     * @param time
     */
    void sendSingleRemind(SigninRecord record, Integer patientId, List<SignInAction> signInActionList, String time);

    /**
     * 保存打卡记录
     *
     * @param dataId
     * @param patientId
     * @param recordType
     * @param subType
     * @param recordDate
     */
    void saveSigninRecord(Integer dataId, Integer patientId, Integer recordType, Integer subType, String recordDate);

    void saveSigninRecord(Integer dataId, CheckinRecord checkinRecord, Integer subType, String recordDate);

    void saveSigninRecord(Integer dataId, Integer subType, Function<Function<Integer, RecordBuilder>, CheckinRecord> mapper);

    /**
     * 成就得分汇总
     */
    void summaryAchievement();

    /**
     * 标记过时未完成的记录
     */
    void tagUnDoneRecord();

    /**
     * 获取打卡记录列表
     *
     * @param patientId
     */
    List<DailyRecord> getDailyRecordListByPatientId(Integer patientId);

    /**
     * 获取患者打卡状况
     */
    PatientMiniProgramSigninStatus getPatientSignStatus(Integer patientId);

    /**
     * 获取患者周报的打卡记录
     */
    ReportTable getReportWeeklySigninRecords(Integer patientId, Date startDate, Date endDate);

    /**
     * 获取患者首页的打卡情况
     */
    PatientSigninStatusBean getPatientIndexSignStatus(Integer patientId);

    /**
     * 通过患者id查询打卡记录
     */
    List<DtrdEntRdSigninRecord> listSigninRecordsByPatientIds(List<Integer> patientIds);

    /**
     * 获取某个患者的打卡记录集合 星期 : 类型 ： 次数
     */
    Map<Integer, Map<Integer, Integer>> getSigninRecordByPatientId(Integer patientId);

    /**
     * 计算患者打卡日期的各星期数量
     */
    Map<Integer, Integer> getPatientSigninRecordWeekDayMap(Integer patientId);

    /**
     * 获取打卡的周平均律
     *
     * @return
     */
    Map<String, String> getSigninFinishedRateWeeklyMap(int patientId, Date startDate, Date endDate);

    /**
     * 查询所有打卡记录
     *
     * @return
     */
    List<DtrdEntRdSigninRecord> getAllSigninRecords();

//    List<DailyGroupCheckinRecord> getSigninRecords(Integer patientId, String startTime, String endTime);

    List<DtrdEntRdSigninRecord> getSigninRecords(Integer patientId, String startTime, String endTime, boolean isDateDesc);

    void sendMissRecordRemind(Integer patientId, List<SignInAction> signInActionList, Integer dataId);
}
